home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 13240 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.7 KB  |  109 lines

  1. Path: mail2news.demon.co.uk!genesis.demon.co.uk
  2. From: Lawrence Kirby <fred@genesis.demon.co.uk>
  3. Newsgroups: comp.lang.c
  4. Subject: Re: how to get weeknumber according calendar
  5. Date: Fri, 05 Apr 96 14:35:32 GMT
  6. Organization: none
  7. Message-ID: <828714932snz@genesis.demon.co.uk>
  8. References: <4jt3jr$j58@hdxx05.telecom.ptt.nl>
  9. Reply-To: fred@genesis.demon.co.uk
  10. X-NNTP-Posting-Host: genesis.demon.co.uk
  11. X-Newsreader: Demon Internet Simple News v1.27
  12. X-Mail2News-Path: genesis.demon.co.uk
  13.  
  14. In article <4jt3jr$j58@hdxx05.telecom.ptt.nl>
  15.            a.broers@ptt-telecom.unisource.nl "Andre Broers" writes:
  16.  
  17. >Hello all,
  18. >
  19. >Hopw can I get a weeknumber following the calendar. This means the
  20. >first days in januari can be week 52, 53 or 1 (and not 0).
  21.  
  22. That doesn't pin an algorithm down very much. However you may be referring
  23. to ISO 8601 week numbers. I have submitted the following for the next
  24. release of Snippets:
  25.  
  26.  
  27. /******************************************************************************
  28.  * weeknum_ISO8601.c       December 1995       L.Kirby
  29.  *
  30.  * Calculates the week number of a day in the year based on the ISO8601 week
  31.  * numbering scheme. The arguments are:
  32.  *
  33.  * t - a pointer to a struct tm in which the following members must be set and
  34.  *     normalised to the standard ranges specified (as standard library
  35.  *     functions gmtime, localtime and mktime should do):
  36.  *     
  37.  *     tm_wday - The day of the week of the day in question:
  38.  *               0-Sunday -> 6-Saturday
  39.  *
  40.  *     tm_yday - The day of the year of the day in question: 0 -> 365
  41.  *               January 1st is day 0.
  42.  *
  43.  *     tm_year - The year since 1900.
  44.  *
  45.  * firstdow - This defines the day of the week on which a week starts:
  46.  *            0-Sunday -> 6-Saturday. For normal ISO8601 weeks that start on
  47.  *            a Monday this should be 1.
  48.  *
  49.  ******************************************************************************
  50.  *
  51.  * The week number is a value between 1 and 53 inclusive defined according to
  52.  * the following rules:
  53.  *
  54.  * 1. The Gregorian calendar is assumed.
  55.  *
  56.  * 2. There are always 7 consecutive days with the same week number.
  57.  *
  58.  * 3. January 4th is defined to be in week 1. Equivalently week 1 is the
  59.  *    first week of a year which has at least 4 days in that year.
  60.  *
  61.  * 4. firstdow defines the day of the week which starts a new week i.e. has
  62.  *    a different week number from the previous day.
  63.  *
  64.  * 5. Week numbers increase in sequence from week 1 until the week that is
  65.  *    defined to be week 1 of the following year.
  66.  *
  67.  * It follows that:
  68.  *
  69.  * 6. Up to January 3rd may be in either week 1 of the current year or in
  70.  *    weeks 52 or 53 of the previous year.
  71.  *
  72.  * 7. 29th December onwards may be in either weeks 52 or 53 of the current
  73.  *    year or week 1 of the following year.
  74.  *
  75.  ******************************************************************************
  76.  */
  77.  
  78. #include <time.h>
  79.  
  80. int weeknum_ISO8601(const struct tm *t, int firstdow)
  81.  
  82. {
  83.     const int tmp1 = firstdow - t->tm_wday;
  84.     const int tmp2 = t->tm_yday + ((tmp1 > 0) ? 3 : 10) + tmp1;
  85.     const int fourthdaynum = tmp2 % 7;
  86.     int     week = tmp2 / 7;
  87.  
  88.     if (week == 0) {
  89.         const int year = t->tm_year + 1900 - 1;
  90.         const int isleap = !(year % 4) && ((year % 100) || !(year % 400));
  91.  
  92.         week = (fourthdaynum + isleap >= 6) ? 53 : 52;
  93.     } else if (week == 53) {
  94.         const int year = t->tm_year + 1900;
  95.         const int isleap = !(year % 4) && ((year % 100) || !(year % 400));
  96.  
  97.         if (fourthdaynum > isleap)
  98.             week = 1;
  99.     }
  100.  
  101.    return week;
  102. }
  103.  
  104. -- 
  105. -----------------------------------------
  106. Lawrence Kirby | fred@genesis.demon.co.uk
  107. Wilts, England | 70734.126@compuserve.com
  108. -----------------------------------------
  109.